#-*- coding:utf8 -*-
from django.test import TestCase

from master.models import UserProfiles
from master.models import Groups
from master.models import Companies
from master.models import Depts
from master.models import DeptTrees

from django.contrib.auth.models import User


from django.db.models import Max
import logging
logger = logging.getLogger(__name__)


class UserProfilesTestCase(TestCase):
    
    def setUp(self):
        user = User.objects.create_user('ok49', 'ok4949@gmail.com', '111')
        group = Groups.objects.create(code='100', name="TestGroup")
        company = Companies.objects.create(group=group, code='C001', name='TestCompany')
        dept = Depts.objects.create(company=company, code='D001', name='TestDept')
        
        self.userProfile = UserProfiles.objects.create(user=user, dept=dept, tel_no='123')
        
        
    def test_foo(self):
        
        profile = UserProfiles.objects.get(user=User.objects.get(username='ok49'))
        
        self.assertEqual(self.userProfile, profile)
        
        
        
        
class DeptTreesTestCase(TestCase):
    
    def setUp(self):
        user = User.objects.create_user('ok49', 'ok4949@gmail.com', '111')
        group = Groups.objects.create(code='100', name="TestGroup")
        self.company = Companies.objects.create(group=group, code='C001', name='TestCompany')
        self.dept = Depts.objects.create(company=self.company, code='R', name='ROOT')
        self.deptTree = DeptTrees.objects.create(ancestor=self.dept, descendant=self.dept, path_length=0)
        
    def test_append_node(self):
        dt = DeptTrees()
        
        
        newDept = Depts.objects.create(company=self.company, code='D002', name='SUB1')
        
        dt.append_node(self.dept, newDept) # 부서 하위 노드를 하나 추가함
        
        self.assertIsNotNone(
            Depts.objects.get(code='D002') 
        ) # append_dept 매서드를 호출했을때 추가한 하위 부서는 Depts에 기록된다.
        
        self.assertEqual(2, len(Depts.objects.all()))
        self.assertEqual(3, len(DeptTrees.objects.all())) # 클로저 테이블에 기록될때는 자신의 노드도 포함된다.
        
        
        parents = DeptTrees.objects.filter(descendant=newDept)
        
        for node in parents:    
            if newDept.code != node.ancestor.code:
                # 상위 노드는 setUp에서 만들어 놓은 객체와 동일하다.
                self.assertEqual(self.dept, node.ancestor)
                
            
        #####################################
        new2thDept = Depts.objects.create(company=self.company, code='D003', name='SUB2')
        dt.append_node(newDept, new2thDept) # 부서 하위 노드를 하나 더 추가함
        
        self.assertEqual(3, len(Depts.objects.all()))
        self.assertEqual(6, len(DeptTrees.objects.all())) 
        
        parents = DeptTrees.objects.filter(descendant=new2thDept)
        self.assertEquals(3, len(parents)) # 부모 노드는 두개에 자기 자신을 포함하여 3
        
        depts = []
        for node in parents:
            depts.append(node.ancestor)
        
        ''' 자기 자신을 포함한 조상 노드는 앞에서 추가한 세 부서정보가 모두 담겨있다.
        '''
        self.assertTrue(self.dept in depts)
        self.assertTrue(newDept in depts)
        self.assertTrue(new2thDept in depts)
        
        
        ''' 최대 노드의 깊이는 2 '''
        self.assertEquals(2, DeptTrees.objects.all().aggregate(Max('path_length'))['path_length__max'])
        
        #####################################
        
        
        
        '''
        DELETE FROM TreePaths
        WHERE descendant IN (SELECT descendant FROM TreePaths WHERE ancestor = 'D')
        AND ancestor NOT IN (SELECT descendant FROM TreePaths WHERE ancestor = 'D');
        
        DELETE FROM TreePaths
        WHERE descendant IN (SELECT descendant FROM TreePaths WHERE ancestor = 'D')
        AND ancestor NOT IN (SELECT descendant FROM TreePaths WHERE ancestor = 'D');
        '''
        
        #print DeptTrees.objects.filter(ancestor=new2thDept)
        k = []
        for i in DeptTrees.objects.filter(ancestor=newDept):
            k.append(i.descendant)
        #print DeptTrees.objects.filter(ancestor=new2thDept)
        
        #print k
        
        
        
        from django.db.models import Q
        #my_objects_list = MyObject.objects.filter(~Q(id=a.id), foreign_key=b, some_field=True)
        
        
        o = DeptTrees.objects.filter(
            
            descendant__in = k  
        )
        
        
        
        
        #for i in o:
        #    print i.ancestor, '||', i.descendant, i.path_length
        
        
        
        #Entry.objects.filter(id__in=[1, 3, 4])
        
        
    def test_remove_node(self):
        dt = DeptTrees()
        
        a = Depts.objects.create(company=self.company, code='A', name='A')
        b = Depts.objects.create(company=self.company, code='B', name='B')
        c = Depts.objects.create(company=self.company, code='C', name='C')
        d = Depts.objects.create(company=self.company, code='D', name='D')
        e = Depts.objects.create(company=self.company, code='E', name='E')
        
        
        dt.append_node(self.dept, a)
        dt.append_node(self.dept, e)
        dt.append_node(a, b)
        dt.append_node(a, d)
        dt.append_node(b, c)
        
        
        
        dt.remove_node(e)
        self.assertEquals(0, len(DeptTrees.objects.filter(descendant=e)))
        
        
        dt.remove_node(a)
        self.assertEquals(0, len(DeptTrees.objects.filter(descendant=a)) )
        self.assertEquals(0, len(DeptTrees.objects.filter(descendant=b)) )
        self.assertEquals(0, len(DeptTrees.objects.filter(descendant=c)) )
        self.assertEquals(0, len(DeptTrees.objects.filter(descendant=d)) )
        
        
        
    def test_move_node(self):
        dt = DeptTrees()
        
        a = Depts.objects.create(company=self.company, code='A', name='A')
        b = Depts.objects.create(company=self.company, code='B', name='B')
        c = Depts.objects.create(company=self.company, code='C', name='C')
        d = Depts.objects.create(company=self.company, code='D', name='D')
        e = Depts.objects.create(company=self.company, code='E', name='E')
        
        dt.append_node(self.dept, a)
        dt.append_node(self.dept, e)
        dt.append_node(a, b)
        dt.append_node(a, d)
        dt.append_node(b, c)
        
        
        dt.move_node(a, e)
        
        
        self.assertEqual(a,
                         DeptTrees.objects.filter(ancestor=e, path_length=1)[0].descendant)
        
        self.assertEquals(
            2,
            len(DeptTrees.objects.filter(ancestor=a, path_length=1))
        )
        
        
        self.assertEquals(
            a,
            DeptTrees.objects.filter(descendant=d, path_length=1)[0].ancestor
        )
        
        
        self.assertEquals(
            b,
            DeptTrees.objects.filter(descendant=c, path_length=1)[0].ancestor
        )
        
        
        
         
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        